package com.lobov.operations.yale;

import com.lobov.entities.Timer;
import com.lobov.entities.yale.MatrixYale;
import com.lobov.entities.yale.SnipYale;

public class MultiplicationYale extends Timer {

	public static MultiplicationYale newInstance() {
		return new MultiplicationYale();
	}

	public MatrixYale matrixOnMatrix(MatrixYale m1, MatrixYale m2,
			boolean printLogs) throws Exception {
		if (m1.getXlength() != m2.getYlength()) {
			throw new Exception(
					"Ошибка !!! Количество строк в первой матрице не равно числу столбцов во второй!!! Перемножение таких матриц невозможно.");
		}
		startTimer(); // стартуем таймер сразу же при начале перемножения
		int xLengthM1 = m1.getXlength();
		int xLengthM2 = m2.getXlength();

		int yLengthM1 = m1.getYlength();
		int yLengthM2 = m2.getYlength();

		int xLengthNew = xLengthM2;
		int yLengthNew = yLengthM1;

		MatrixYale newMatrix = new MatrixYale(xLengthNew, yLengthNew);
		double a = 0;
		double b = 0;
		for (int y1 = 1; y1 <= yLengthM1; y1++) {
			for (int x2 = 1; x2 <= xLengthM2; x2++) {
				double summ = 0;
				for (int x1 = 1; x1 <= xLengthM1; x1++) {
					a = m1.getElementByXY(x1, y1); 
					if (a == 0d) {
						continue;
					}
					b = m2.getElementByXY(x2, x1);
					if (b == 0d) {
						continue;
					}
					summ += a * b;
				}
				newMatrix.setElementByXY(x2, y1, summ);
			}
		}
		stopTimer();
		return newMatrix;
	}

	public SnipYale snipOnMatrix(SnipYale snip, MatrixYale matrix, boolean printLogs)
			throws Exception {
		if (snip.getXlength() != matrix.getYlength()) {
			throw new Exception(
					"Ошибка !!! Количество строк в матрице не равно числу столбцов в лоскуте!!! Перемножение таких сущностей невозможно.");
		}
		startTimer(); // стартуем таймер сразу же при начале перемножения
		int xLengthM1 = snip.getXlength();
		int xLengthM2 = matrix.getXlength();

		int yLengthM1 = snip.getYlength();
		int yLengthM2 = matrix.getYlength();

		int xLengthNew = xLengthM2;
		int yLengthNew = yLengthM1;

		SnipYale newSnip = new SnipYale(xLengthNew, yLengthNew, snip.getOrderNumInContainer());
		double a = 0;
		double b = 0;
		for (int y1 = 1; y1 <= yLengthM1; y1++) {
			for (int x2 = 1; x2 <= xLengthM2; x2++) {
				double summ = 0;
				for (int x1 = 1; x1 <= xLengthM1; x1++) {
					a = snip.getElementByXY(x1, y1); 
					if (a == 0d) {
						continue;
					}
					b = matrix.getElementByXY(x2, x1);
					if (b == 0d) {
						continue;
					}
					summ += a * b;
				}
				newSnip.setElementByXY(x2, y1, summ);
			}
		}
		stopTimer();
		return newSnip;
	}
}
